/*
 * BoxSelector.cpp
 *
 *  Created on: Oct 14, 2013
 *      Author: filipe
 */

#include "BoxSelector.h"


void
mouse_event_handler_wrapper(int event, int x, int y, int flags, void *param)
{
	BoxSelector *box_selector = (BoxSelector *) param;
	box_selector->MouseEventHandler(event, x, y, flags, NULL);
}


void
BoxSelector::_DefaultConstructor()
{
	_box = cv::Rect(0, 0, 0, 0);
	_box_selected = false;
	_mouse_pressed = false;
}


BoxSelector::BoxSelector()
{
	_DefaultConstructor();
}


BoxSelector::BoxSelector(cv::Mat &img)
{
	_DefaultConstructor();
	_reference_image = cv::Mat(img);
}


BoxSelector::BoxSelector(std::string filename)
{
	_DefaultConstructor();
	_reference_image = cv::imread(filename);
}


BoxSelector::~BoxSelector()
{
}


void
BoxSelector::SetImage(cv::Mat &img)
{
	_reference_image = cv::Mat(img);
	_box_selected = false;
}


void
BoxSelector::SetBox(cv::Rect box)
{
	_box = cv::Rect(box);
}


cv::Rect
BoxSelector::GetBox(void) const
{
	return _box;
}


void
BoxSelector::Loop(void)
{
	cv::namedWindow("image", 1);
	cv::setMouseCallback("image", mouse_event_handler_wrapper, this);

	while(cvWaitKey(5) != 'q')
	{
		_viewer_image = _reference_image.clone();

		cv::rectangle(_viewer_image,
			cv::Point(_box.x, _box.y),
			cv::Point(_box.x + _box.width, _box.y + _box.height),
			cv::Scalar(0, 0, 255));

		cv::imshow("image", _viewer_image);
	}

	cvDestroyWindow("image");
}


bool
BoxSelector::BoxSelected() const
{
	return _box_selected;
}


void
BoxSelector::MouseEventHandler(int event, int x, int y, int flags, void* param)
{
	if (event == CV_EVENT_LBUTTONDOWN)
	{
		_box = cv::Rect(x, y, 0, 0);
		_mouse_pressed = true;
	}
	else
	{
		int y_up = MYMIN(_box.y, y);
		int x_left = MYMIN(_box.x, x);

		int width = abs(_box.x - x);
		int height = abs(_box.y - y);

		if ((event == CV_EVENT_LBUTTONUP))
		{
			_box = cv::Rect(x_left, y_up, width, height);
			_mouse_pressed = false;
			_box_selected = true;
		}
		else
		{
			// only for visualization
			if (_mouse_pressed)
				_box = cv::Rect(x_left, y_up, width, height);
		}
	}
}

